package com.hlab.fabrevealmenu.helper;

import com.hlab.fabrevealmenu.utils.ColorUtils;
import com.hlab.fabrevealmenu.utils.DensityUtils;

import ohos.agp.colors.RgbColor;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.ListContainer;
import ohos.agp.components.StackLayout;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.app.Context;

/**
 * ViewHelper
 *
 * @since 2021-05-14
 */
public class ViewHelper {
    private final Context mContext;
    private final ComponentContainer.LayoutConfig matchParams;
    private final ComponentContainer.LayoutConfig wrapParams;

    /**
     * ViewHelper
     *
     * @param context context
     */
    public ViewHelper(Context context) {
        mContext = context;
        matchParams = new ComponentContainer.LayoutConfig(
                ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT);
        wrapParams = new ComponentContainer.LayoutConfig(
                ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_CONTENT);
    }

    /**
     * generateBaseView
     *
     * @param radius radius
     * @param color color
     * @return DependentLayout
     */
    public DependentLayout generateBaseView(int radius, int color) {
        // Base view
        DependentLayout mBaseView = new DependentLayout(mContext);
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setCornerRadius(DensityUtils.fpToPx(mContext,radius));
        shapeElement.setRgbColor(getRgbColor(color));
        mBaseView.setBackground(shapeElement);
        mBaseView.setLayoutConfig(matchParams);
        return mBaseView;
    }

    /**
     * generateMenuView
     *
     * @param isEnableNestedScrolling isEnableNestedScrolling
     * @return ListContainer
     */
    public ListContainer generateMenuView(boolean isEnableNestedScrolling) {
        // Create menu view
        ListContainer mMenuView = new ListContainer(mContext);

        // 设置背景透明
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(new RgbColor(0,0,0,0));
        mMenuView.setBackground(shapeElement);
        mMenuView.setLayoutConfig(wrapParams);
        final int padding = DensityUtils.fpToPx(mContext, 10);
        mMenuView.setPadding(padding, padding, padding, padding);
        mMenuView.setScrollbarOverlapEnabled(isEnableNestedScrolling);
        return mMenuView;
    }

    /**
     * generateRevealView
     *
     * @return DirectionalLayout
     */
    public DirectionalLayout generateRevealView() {
        // Reveal view
        DirectionalLayout mRevealView = new DirectionalLayout(mContext);
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(new RgbColor(0,0,0,0));

        // 设置背景透明
        mRevealView.setBackground(shapeElement);
        mRevealView.setLayoutConfig(wrapParams);
        mRevealView.setVisibility(Component.INVISIBLE);
        return mRevealView;
    }

    /**
     * generateOverlayView
     *
     * @param isShowOverlay isShowOverlay
     * @param color color
     * @return StackLayout
     */
    public StackLayout generateOverlayView(boolean isShowOverlay, int color) {
        // Overlay view
        StackLayout mOverlayLayout = new StackLayout(mContext);
        mOverlayLayout.setLayoutConfig(matchParams);
        mOverlayLayout.setAlpha(0);
        mOverlayLayout.setVisibility(Component.INVISIBLE);
        mOverlayLayout.setClickable(true);
        ShapeElement shapeElementOver = new ShapeElement();
        if (isShowOverlay) {
            shapeElementOver.setRgbColor(getRgbColor(color));
        } else {
            shapeElementOver.setRgbColor(new RgbColor(0,0,0,0));
        }
        mOverlayLayout.setBackground(shapeElementOver);
        return mOverlayLayout;
    }

    /**
     * setLayoutParams
     *
     * @param component component
     */
    public void setLayoutParams(Component component) {
        component.setLayoutConfig(wrapParams);
    }

    /**
     * Aligns the sheet's position with the FAB.
     *
     * @param fab fab
     * @param revealView revealView
     * @param direction direction
     */
    public void alignMenuWithFab(Component fab, Component revealView, Direction direction) {
        ComponentContainer.LayoutConfig sheetLayoutParams = fab.getLayoutConfig();
        ComponentContainer.LayoutConfig fabLayoutParams = revealView.getLayoutConfig();

        // adjust sheet margin
        sheetLayoutParams.setMargins(
                fabLayoutParams.getMarginLeft(), fabLayoutParams.getMarginTop(),
                fabLayoutParams.getMarginRight(), fabLayoutParams.getMarginBottom());

        // Get FAB's coordinates
        int[] fabCoords = fab.getLocationOnScreen();

        // Get sheet's coordinates
        int[] sheetCoords = revealView.getLocationOnScreen();

        int leftDiff = Math.max(sheetCoords[0] - fabCoords[0], fabLayoutParams.getMarginLeft());
        int rightDiff = Math.min((sheetCoords[0] + revealView.getWidth())
                - (fabCoords[0] + fab.getWidth()), -fabLayoutParams.getMarginRight());
        int topDiff = Math.max(sheetCoords[1] - fabCoords[1], fabLayoutParams.getMarginTop());
        int bottomDiff = Math.min((sheetCoords[1] + revealView.getHeight())
                - (fabCoords[1] + fab.getHeight()), -fabLayoutParams.getMarginBottom());

        float sheetX = revealView.getContentPositionX();
        float sheetY = revealView.getContentPositionY();

        if (direction == Direction.LEFT || direction == Direction.UP) {
            // Align the right side of the sheet with the right side of the FAB
            revealView.setContentPositionX(sheetX - rightDiff - sheetLayoutParams.getMarginRight());

            // Align the bottom of the sheet with the bottom of the FAB
            revealView.setContentPositionY(sheetY - bottomDiff - sheetLayoutParams.getMarginBottom());
        } else if (direction == Direction.RIGHT) {
            // align the left side of the sheet with the left side of the FAB
            revealView.setContentPositionX(sheetX - leftDiff + sheetLayoutParams.getMarginLeft());

            // Align the bottom of the sheet with the bottom of the FAB
            revealView.setContentPositionY(sheetY - bottomDiff - sheetLayoutParams.getMarginBottom());
        } else if (direction == Direction.DOWN) {
            // align the top of the sheet with the top of the FAB
            revealView.setContentPositionY(sheetY - topDiff + sheetLayoutParams.getMarginTop());

            // Align the right side of the sheet with the right side of the FAB
            revealView.setContentPositionX(sheetX - rightDiff - sheetLayoutParams.getMarginRight());
        }
    }

    /**
     * getRgbColor
     *
     * @param color color
     * @return RgbColor
     */
    public RgbColor getRgbColor(int color) {
        return new RgbColor(ColorUtils.redInt(color),
                ColorUtils.greenInt(color),ColorUtils.blueInt(color), Color.alpha(color));
    }
}
